package com.zhangxx.inventory.thread.asyncProcessService.impl;

import com.google.common.base.Joiner;
import com.zhangxx.inventory.pojo.ProductInventory;
import com.zhangxx.inventory.thread.asyncProcessService.RequestAsyncProcessService;
import com.zhangxx.inventory.thread.request.Request;
import com.zhangxx.inventory.thread.request.RequestQueue;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.concurrent.ArrayBlockingQueue;

/**
 * @ClassName RequestAsyncProcessServiceImpl
 * @Description 异步请求实现类
 * @Author leizhang
 * Date 2022/3/18 20:10
 * @Version 1.0
 **/
@Service
@Slf4j
public class RequestAsyncProcessServiceImpl implements RequestAsyncProcessService {
    private static final Joiner JOINER = Joiner.on("_").skipNulls();
    /**
     * @Description : 根据请求的product信息，将相同的product的hashcode打到对应的队列上
     * @Author : leizhang
     * @Date 20:11 2022/3/18
     * @param request
     * @return void
     **/
    @Override
    public void process(Request request) {
        ArrayBlockingQueue<Request> routingQueue = this.getRoutingQueue(request.getProductInfo());
        try {
            routingQueue.put(request);
        } catch (InterruptedException e) {
           log.info("请求队列分步：{}",e.getMessage());
        }
    }

    /**
     * @Description : 根据hash 计算出对应的队列
     * @Author : leizhang
     * @Date 20:14 2022/3/18
     * @param productInventory
     * @return java.util.concurrent.ArrayBlockingQueue<com.zhangxx.inventory.thread.request.Request>
     **/
    private ArrayBlockingQueue<Request> getRoutingQueue(ProductInventory productInventory){
        RequestQueue requestQueue = RequestQueue.getInstance();
        String key = JOINER.join(productInventory.getWarehousCode(),productInventory.getStockCode(),productInventory.getProductId());
        //计算key对应的hash
        int h;
        int hash = (key == null)?0:( h = key.hashCode())^(h>>>16);
        int index = (requestQueue.queueSize()-1) & hash;
        return requestQueue.getQueue(index);
    }
}
